package com.ushine.web.component.task.aop;

import com.ushine.web.component.exception.ServiceException;
import com.ushine.web.component.exception.ServiceExceptionEnum;
import com.ushine.web.component.task.AsyncTaskManager;
import com.ushine.web.component.task.model.AsyncTaskInfoDO;
import com.ushine.web.component.task.TaskStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Author: yls
 * @Date: 2021/04/28 22:44
 * @Description: 异步任务监控
 * @Version 1.0
 */
@Component
@Aspect
@Slf4j
public class AsyncTaskMonitor {

    @Resource
    AsyncTaskManager asyncTaskManager;

    @Around("execution(* com.ushine.web.component.task.exector.AsyncDefaultTaskExecutor.*(..))")
    public Object taskHandle(ProceedingJoinPoint point) throws ServiceException {
        // 获取任务id
        AsyncTaskInfoDO taskInfo = (AsyncTaskInfoDO) point.getArgs()[0];
        Long taskId = taskInfo.getId();
        log.info("监控任务：{}", taskId);
        TaskStatusEnum status;
        Object proceed;
        try {
            log.error("异步任务：{} 开始执行", taskId);
            taskInfo.setStatus(TaskStatusEnum.RUNNING.getState());
            asyncTaskManager.updateTaskInfo(taskInfo);
            // 执行具体的业务逻辑
            proceed = point.proceed();

        } catch (Throwable throwable) {
            status = TaskStatusEnum.FAILED;
            log.error("异步任务：{} 执行失败，错误信息：{}", taskId, throwable.getMessage());
            String errMsg = "异步任务：" + taskId + " 执行失败，错误信息：" + throwable.getMessage();
            taskInfo.setErrMsg(errMsg);
            updateTaskInfo(taskInfo, status);
            throw new ServiceException(ServiceExceptionEnum.ASYNC_TASK_ERROR, throwable);
        }
        status = TaskStatusEnum.SUCCESS;
        updateTaskInfo(taskInfo, status);
        log.error("异步任务：{} 执行完成", taskId);
        return proceed;
    }

    /**
     * 功能描述:
     * 〈 更新任务信息 〉
     *
     * @param taskInfo 任务信息
     * @param status   任务状态
     * @author : yls
     * @date : 2022/02/21 11:08
     */
    private void updateTaskInfo(AsyncTaskInfoDO taskInfo, TaskStatusEnum status) {
        taskInfo.setEndTime(new Date());
        taskInfo.setStatus(status.getState());
        /*
         * 执行总耗时
         */
        long totalTime = taskInfo.getEndTime().getTime() - taskInfo.getStartTime().getTime();
        taskInfo.setTotalTime(totalTime);
        asyncTaskManager.updateTaskInfo(taskInfo);
    }

}
